home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / PowerPlant / DMultiStringLocator / source / CSearchWindow.cp next >
Text File  |  1996-07-06  |  8KB  |  261 lines

  1. // ===========================================================================
  2. // CSearchWindow.cp
  3. //   ---------------------
  4. //   ©1996 Eric Gundrum, All rights reserved.
  5. //   The contents of this file may be freely altered and freely distributed
  6. //   in any form, provided this copyright statement is retained unaltered.
  7. //   Add your own changes below.
  8. //   ---------------------
  9. //    
  10. //    Coordinate activities of the Search Window.  
  11. //    This is pretty crappy code.
  12. //
  13.  
  14. // PowerPlant Headers
  15. #include <LFileStream.h>
  16. #include <UDebugging.h>
  17. #include <UException.h>
  18. #include <UReanimator.h>
  19.  
  20. // Library Headers
  21.  
  22. // Project Headers
  23. #include "CSearchWindow.h"
  24.  
  25.  
  26. // ===========================================================================
  27. #pragma mark --- static CSearchString ---
  28. // ===========================================================================
  29. long    CSearchString::mBufferOffset    = 0;    // static initializer
  30.  
  31.  
  32. // ===========================================================================
  33. #pragma mark --- public CSearchWindow ---
  34. // ===========================================================================
  35.  
  36. // ---------------------------------------------------------------------------
  37. //    Constructor
  38.  
  39. CSearchWindow::CSearchWindow()
  40. {
  41.     ShowSearchWindow();
  42. }
  43.  
  44.  
  45. // ---------------------------------------------------------------------------
  46. //    Request search criteria from the user
  47. void
  48. CSearchWindow::ShowSearchWindow()
  49. {
  50.     mSearchWindowP    =  LWindow::CreateWindow( window_Search, this );
  51.     
  52.     UReanimator::LinkListenerToControls( this, mSearchWindowP, window_Search );
  53.     
  54.     mSearchWindowP    -> Show();
  55. }
  56.  
  57.  
  58. // ---------------------------------------------------------------------------
  59. //    
  60. void
  61. CSearchWindow::ListenToMessage
  62. (    MessageT    inMessage
  63. ,    void*        ioParam
  64. )
  65. {
  66.     switch( inMessage )
  67.     {
  68.         case msg_FilterExecute:
  69.             DoSearch();
  70.             break;
  71.             
  72.         case msg_FilterCancel:
  73.             LCommander::ObeyCommand(cmd_Quit, ioParam);
  74.             // delete mSearchWindowP;    // ••• probably not safe
  75.             // ••• also should destroy this object, but I don't know how yet
  76.             break;
  77.             
  78.         case msg_BroadcasterDied:
  79.             mSearchWindowP    = nil;    // delete is built into LWindow
  80.             break;
  81.     }
  82. }
  83.  
  84.  
  85. // ---------------------------------------------------------------------------
  86. //    
  87. void
  88. CSearchWindow::DoSearch()
  89. {
  90.     
  91.     // process the contents of the search window into a CSearchString list
  92.     LEditField    *theEditFieldP    = nil;
  93.     
  94.     theEditFieldP    = dynamic_cast<LEditField*>
  95.                         (mSearchWindowP->FindPaneByID( editField_Target1 ));
  96.     InsertSearchItem( 1, *theEditFieldP );
  97.     theEditFieldP    = dynamic_cast<LEditField*>
  98.                         (mSearchWindowP->FindPaneByID( editField_Target2 ));
  99.     InsertSearchItem( 2, *theEditFieldP );
  100.     theEditFieldP    = dynamic_cast<LEditField*>
  101.                         (mSearchWindowP->FindPaneByID( editField_Target3 ));
  102.     InsertSearchItem( 3, *theEditFieldP );
  103.     
  104.     // ask for the file to search
  105.     StandardFileReply    theReply;
  106.     ::StandardGetFile( nil, -1, nil, &theReply );
  107.     if ( true == theReply.sfGood )
  108.     {
  109.         LFileStream        target( theReply.sfFile );
  110.         
  111.         // do the search
  112.         long    startTime    = ::TickCount();
  113.         SearchFile( target );
  114.         long    duration    = (::TickCount() - startTime + 30)/60;
  115.         
  116.         // report results
  117.         CSearchString    *searchItemP        = nil;
  118.         LCaption        *resultsCaptionP    = nil;
  119.         LStr255            countStr;
  120.         
  121.         mSearchList.FetchItemAt( 1, &searchItemP );
  122.         resultsCaptionP    = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Result1 ));
  123.         resultsCaptionP -> SetDescriptor( countStr.Assign( searchItemP->GetFoundCount() ) );
  124.         
  125.         mSearchList.FetchItemAt( 2, &searchItemP );
  126.         resultsCaptionP    = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Result2 ));
  127.         resultsCaptionP -> SetDescriptor( countStr.Assign( searchItemP->GetFoundCount() ) );
  128.         
  129.         mSearchList.FetchItemAt( 3, &searchItemP );
  130.         resultsCaptionP    = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Result3 ));
  131.         resultsCaptionP -> SetDescriptor( countStr.Assign( searchItemP->GetFoundCount() ) );
  132.         
  133.         resultsCaptionP    = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Duration ));
  134.         resultsCaptionP -> SetDescriptor( countStr.Assign( duration ) );
  135.     }
  136.     EmptySearchList();        // prepare it for the next use
  137.     ::SysBeep(1);
  138. }
  139.  
  140.  
  141. // ---------------------------------------------------------------------------
  142. //    Open and read a file, calling a SearchBuffer reapeatedly until the entire 
  143. //    file is searched.
  144. //
  145. //    Backup the stream to correct for partial matches at the end of the buffer.
  146. void
  147. CSearchWindow::SearchFile( LFileStream &inTarget )
  148. {
  149.     const    int            bufferSize    = 4096;    // should be at least 4096 for efficiency
  150.             int            bytesRead, partialMatch;
  151.             Uchar        *bufferP    = new Uchar[bufferSize];
  152.             EventRecord    theEvent;
  153.             
  154.     DMultiStringLocator locator( mSearchList );        // search engine
  155.     
  156.     // validate inputs
  157.     ThrowIfNil_( &inTarget );
  158.     
  159.     inTarget.OpenDataFork( fsRdPerm );
  160.     while ( !inTarget.AtEnd() )        // for each buffer...
  161.     {
  162.         // read file data into a buffer
  163.         CSearchString::SetBufferOffset( inTarget.GetMarker() );
  164.         bytesRead     = inTarget.ReadData( bufferP, bufferSize );
  165.         if( (bytesRead < bufferSize) && !inTarget.AtEnd() )
  166.         {
  167.             SignalCStr_("File Read Error Occurred.");
  168.         }
  169.         
  170.         partialMatch    = locator.SearchBuffer( bufferP, bytesRead );
  171.         if ( DMultiStringLocator::searchStatus_stop == partialMatch ) 
  172.         {
  173.             inTarget.SetMarker( 0, streamFrom_End );
  174.         }
  175.         else if ( !inTarget.AtEnd() )     // backup to re-search partial match
  176.         {
  177.             inTarget.SetMarker( -1*partialMatch, streamFrom_Marker );
  178.         }
  179.         // give some time back to the system
  180.         ::EventAvail ( keyDownMask, &theEvent );
  181.     }
  182.     inTarget.CloseDataFork();
  183. }
  184.  
  185.  
  186. // ---------------------------------------------------------------------------
  187. //        • AllowSubRemoval
  188. // ---------------------------------------------------------------------------
  189. //    This function returns true if a subcommander can be removed as would occur 
  190. //    from clicking the close box in a window.
  191. //
  192. //    This is a convenient place to take settings from the window and save them.
  193. //    AttempQuitSelf is a better place.
  194.  
  195. Boolean
  196. CSearchWindow::AllowSubRemoval( LCommander *inSubP )
  197. {
  198.     mSearchWindowP    = nil;    // ••• until there is code to process the data
  199.     
  200.     if ( inSubP == mSearchWindowP ) 
  201.     {
  202.         ((LWindow *) inSubP)->Hide();
  203.         // process close of window through close box
  204.         
  205.         return false;
  206.     } 
  207.     else
  208.     {
  209.         return true;
  210.     }
  211. }
  212.  
  213.  
  214. // ---------------------------------------------------------------------------
  215. //    Destructor.
  216. CSearchWindow::~CSearchWindow()
  217. {
  218. }
  219.  
  220.  
  221. // ===========================================================================
  222. #pragma mark --- private CSearchWindow ---
  223. // ===========================================================================
  224.  
  225. // ---------------------------------------------------------------------------
  226. //    Place a search item in the list of searchable items.
  227. void
  228. CSearchWindow::InsertSearchItem( Int32 inPos, LEditField &inEditField )
  229. {
  230.     CSearchString        *theStringP    = new CSearchString();
  231.     
  232.     ThrowIfMemFail_( theStringP );
  233.     ThrowIfNil_( &inEditField );        // validate input
  234.     
  235.     inEditField.GetDescriptor( *theStringP );    // zero length items are OK
  236.     mSearchList.InsertItemsAt( 1, inPos, &theStringP );
  237. }
  238.  
  239.  
  240. // ---------------------------------------------------------------------------
  241. //    Empty contents of search list.
  242. void
  243. CSearchWindow::EmptySearchList()
  244. {
  245.     // destroy each item in the search list
  246.     CSearchString        *itemP    = nil;
  247.     LListIterator    searchList ( mSearchList, iterate_FromStart );
  248.     while ( searchList.Next ( &itemP ) )    // for each item...
  249.     {
  250.         ThrowIfNil_( itemP );
  251.         delete itemP;
  252.     }
  253.     // empty the list
  254.     mSearchList.RemoveItemsAt( mSearchList.GetCount(), arrayIndex_First );
  255. }
  256.  
  257.  
  258.  
  259. // ===========================================================================
  260.  
  261.